using Microsoft.Extensions.Logging;
using Serilog;
using JGSY.CMS.LowCode.Platform.Infrastructure.Configuration.Models;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Configuration;

/// <summary>
/// 增强版配置处理器 - 为ConfigurationAccessor提供专门的静态处理方法
/// 整合所有配置相关的switch逻辑，提供统一的配置处理入口
/// 
/// 设计说明：
/// - 使用 Microsoft.Extensions.Logging.ILogger 作为参数类型，符合 .NET 标准
/// - 内部使用 Serilog 进行具体的日志配置，获得强大的结构化日志功能
/// - 这种混合方式兼顾了标准性和功能性
/// </summary>
public static class EnhancedConfigurationProcessor
{
    #region Serilog数据库配置处理

    /// <summary>
    /// 配置Serilog数据库日志记录 - 静态版本
    /// </summary>
    /// <param name="loggerConfig">Serilog配置</param>
    /// <param name="dbType">数据库类型</param>
    /// <param name="connectionString">连接字符串</param>
    /// <param name="logger">可选的日志记录器</param>
    public static void ConfigureSerilogDatabase(LoggerConfiguration loggerConfig, string dbType, string? connectionString = null, Microsoft.Extensions.Logging.ILogger? logger = null)
    {
        // 如果没有提供连接字符串，自动获取
        if (string.IsNullOrEmpty(connectionString))
        {
            connectionString = GetDatabaseConnectionString(dbType);
        }

        var normalizedType = UnifiedConfigurationProcessor.NormalizeDatabaseType(dbType);

        switch (normalizedType)
        {
            case UnifiedConfigurationProcessor.DatabaseType.PostgreSQL:
                ConfigurePostgreSQLSerilog(loggerConfig, connectionString, logger);
                break;
                
            case UnifiedConfigurationProcessor.DatabaseType.SqlServer:
                ConfigureSqlServerSerilog(loggerConfig, connectionString, logger);
                break;
                
            case UnifiedConfigurationProcessor.DatabaseType.MySQL:
                ConfigureMySQLSerilog(loggerConfig, connectionString, logger);
                break;
                
            default:
                logger?.LogWarning("⚠️ 不支持的数据库类型用于日志记录，跳过数据库日志配置");
                break;
        }
    }

    /// <summary>
    /// 获取数据库连接字符串 - 静态版本
    /// </summary>
    /// <param name="dbType">数据库类型</param>
    /// <returns>连接字符串</returns>
    public static string GetDatabaseConnectionString(string dbType)
    {
        var normalizedType = UnifiedConfigurationProcessor.NormalizeDatabaseType(dbType);
        var key = UnifiedConfigurationProcessor.GetConnectionStringKey(normalizedType);
        var connectionString = ConfigurationAccessor.GetConnectionString(key);
        
        if (string.IsNullOrEmpty(connectionString))
        {
            connectionString = GetDefaultConnectionString(normalizedType);
        }
        
        return connectionString;
    }

    #endregion

    #region 数据库特定配置方法

    /// <summary>
    /// 配置PostgreSQL Serilog
    /// </summary>
    private static void ConfigurePostgreSQLSerilog(LoggerConfiguration loggerConfig, string connectionString, Microsoft.Extensions.Logging.ILogger? logger)
    {
        if (!string.IsNullOrEmpty(connectionString))
        {
            // 注意：需要安装 Serilog.Sinks.PostgreSQL NuGet包
            logger?.LogInformation("🗄️ 配置PostgreSQL进行日志记录: {ConnectionString}", MaskConnectionString(connectionString));
            // loggerConfig.WriteTo.PostgreSQL(connectionString, "Logs");
        }
    }

    /// <summary>
    /// 配置SqlServer Serilog
    /// </summary>
    private static void ConfigureSqlServerSerilog(LoggerConfiguration loggerConfig, string connectionString, Microsoft.Extensions.Logging.ILogger? logger)
    {
        if (!string.IsNullOrEmpty(connectionString))
        {
            // 注意：需要安装 Serilog.Sinks.MSSqlServer NuGet包
            logger?.LogInformation("🗄️ 配置SqlServer进行日志记录: {ConnectionString}", MaskConnectionString(connectionString));
            // loggerConfig.WriteTo.MSSqlServer(connectionString, "Logs");
        }
    }

    /// <summary>
    /// 配置MySQL Serilog
    /// </summary>
    private static void ConfigureMySQLSerilog(LoggerConfiguration loggerConfig, string connectionString, Microsoft.Extensions.Logging.ILogger? logger)
    {
        if (!string.IsNullOrEmpty(connectionString))
        {
            // 注意：需要安装 Serilog.Sinks.MySQL NuGet包
            logger?.LogInformation("🗄️ 配置MySQL进行日志记录: {ConnectionString}", MaskConnectionString(connectionString));
            // loggerConfig.WriteTo.MySQL(connectionString);
        }
    }

    #endregion

    #region 缓存配置处理

    /// <summary>
    /// 配置缓存服务 - 根据配置类型选择缓存实现
    /// </summary>
    /// <returns>缓存类型和连接信息</returns>
    public static (string Type, string ConnectionString, Dictionary<string, object> Options) ProcessCacheConfiguration()
    {
        var cacheConfig = ConfigurationAccessor.CacheConfig;
        
        return cacheConfig.Type.ToLower() switch
        {
            "redis" => ProcessRedisCache(cacheConfig),
            "memory" => ProcessMemoryCache(cacheConfig),
            "memcached" => ProcessMemcachedCache(cacheConfig),
            "dragonfly" => ProcessDragonflyCache(cacheConfig),
            _ => ProcessMemoryCache(cacheConfig) // 默认使用内存缓存
        };
    }

    /// <summary>
    /// 处理Redis缓存配置
    /// </summary>
    private static (string Type, string ConnectionString, Dictionary<string, object> Options) ProcessRedisCache(CacheConfiguration config)
    {
        var redis = config.Redis;
        return ("Redis", redis.ConnectionString, new Dictionary<string, object>
        {
            ["Password"] = redis.Password,
            ["Database"] = redis.Database,
            ["MaxRetries"] = redis.MaxRetries,
            ["RetryDelay"] = redis.RetryDelay,
            ["ConnectionTimeout"] = redis.ConnectionTimeout,
            ["CommandTimeout"] = redis.CommandTimeout
        });
    }

    /// <summary>
    /// 处理内存缓存配置
    /// </summary>
    private static (string Type, string ConnectionString, Dictionary<string, object> Options) ProcessMemoryCache(CacheConfiguration config)
    {
        return ("Memory", string.Empty, new Dictionary<string, object>
        {
            ["SizeLimit"] = config.TestTTL
        });
    }

    /// <summary>
    /// 处理Memcached缓存配置
    /// </summary>
    private static (string Type, string ConnectionString, Dictionary<string, object> Options) ProcessMemcachedCache(CacheConfiguration config)
    {
        var memcached = config.Memcached;
        var servers = string.Join(",", memcached.Servers.Select(s => $"{s.Host}:{s.Port}"));
        
        return ("Memcached", servers, new Dictionary<string, object>
        {
            ["ConnectionTimeout"] = memcached.ConnectionTimeout
        });
    }

    /// <summary>
    /// 处理Dragonfly缓存配置
    /// </summary>
    private static (string Type, String ConnectionString, Dictionary<string, object> Options) ProcessDragonflyCache(CacheConfiguration config)
    {
        var dragonfly = config.Dragonfly;
        return ("Dragonfly", dragonfly.Url, new Dictionary<string, object>
        {
            ["ConnectionTimeout"] = dragonfly.ConnectionTimeout
        });
    }

    #endregion

    #region 云存储配置处理

    /// <summary>
    /// 处理云存储配置 - 根据配置选择存储提供商
    /// </summary>
    /// <returns>存储配置信息</returns>
    public static (string Provider, Dictionary<string, string> Settings) ProcessCloudStorageConfiguration()
    {
        var cloudConfig = ConfigurationAccessor.CloudStorageConfig;
        
        if (cloudConfig.AliyunOss.Enabled)
        {
            return ProcessAliyunOssStorage(cloudConfig.AliyunOss);
        }
        
        // 默认返回本地存储
        return ("Local", new Dictionary<string, string>
        {
            ["BasePath"] = ConfigurationAccessor.UploadPath,
            ["BaseUrl"] = ConfigurationAccessor.UploadBaseUrl
        });
    }

    /// <summary>
    /// 处理阿里云OSS存储配置
    /// </summary>
    private static (string Provider, Dictionary<string, string> Settings) ProcessAliyunOssStorage(AliyunOssConfiguration config)
    {
        return ("AliyunOss", new Dictionary<string, string>
        {
            ["Endpoint"] = config.Endpoint,
            ["AccessKeyId"] = config.AccessKeyId,
            ["AccessKeySecret"] = config.AccessKeySecret,
            ["BucketName"] = config.BucketName,
            ["BaseUrl"] = config.BaseUrl ?? $"https://{config.BucketName}.{config.Endpoint}"
        });
    }

    #endregion

    #region 权限配置处理

    /// <summary>
    /// 处理权限配置 - 根据配置决定权限策略
    /// </summary>
    /// <returns>权限配置信息</returns>
    public static (bool Enabled, List<string> DefaultRoles, List<string> AdminRoles, bool StrictMode) ProcessPermissionConfiguration()
    {
        var permissionConfig = ConfigurationAccessor.PermissionConfig;
        
        return (
            permissionConfig.Enabled,
            permissionConfig.DefaultRoles,
            permissionConfig.AdminRoles,
            permissionConfig.StrictMode
        );
    }

    #endregion

    #region CORS配置处理

    /// <summary>
    /// 处理CORS配置 - 根据配置设置跨域策略
    /// </summary>
    /// <returns>CORS配置信息</returns>
    public static (bool Enabled, string[] AllowedOrigins, string[] AllowedMethods, string[] AllowedHeaders, bool AllowCredentials) ProcessCorsConfiguration()
    {
        var corsConfig = ConfigurationAccessor.CorsConfig;
        
        return (
            corsConfig.Enabled,
            corsConfig.AllowedOrigins.ToArray(),
            corsConfig.AllowedMethods.ToArray(),
            corsConfig.AllowedHeaders.ToArray(),
            corsConfig.AllowCredentials
        );
    }

    #endregion

    #region 辅助方法

    /// <summary>
    /// 获取默认连接字符串
    /// </summary>
    /// <param name="dbType">数据库类型</param>
    /// <returns>默认连接字符串</returns>
    private static string GetDefaultConnectionString(UnifiedConfigurationProcessor.DatabaseType dbType)
    {
        return dbType switch
        {
            UnifiedConfigurationProcessor.DatabaseType.SqlServer => "Server=(localdb)\\mssqllocaldb;Database=LowCodePlatform;Trusted_Connection=true;MultipleActiveResultSets=true",
            UnifiedConfigurationProcessor.DatabaseType.MySQL => "Server=localhost;Database=lowcode;Uid=root;Pwd=123456;",
            UnifiedConfigurationProcessor.DatabaseType.PostgreSQL => "Host=localhost;Database=lowcode;Username=postgres;Password=123456",
            _ => throw new NotSupportedException($"不支持的数据库类型: {dbType}")
        };
    }

    /// <summary>
    /// 掩码连接字符串中的敏感信息
    /// </summary>
    private static string MaskConnectionString(string connectionString)
    {
        if (string.IsNullOrEmpty(connectionString))
            return string.Empty;

        var parts = connectionString.Split(';');
        var maskedParts = new List<string>();

        foreach (var part in parts)
        {
            if (part.Contains("Password", StringComparison.OrdinalIgnoreCase) ||
                part.Contains("Pwd", StringComparison.OrdinalIgnoreCase))
            {
                var keyValue = part.Split('=');
                if (keyValue.Length == 2)
                    maskedParts.Add($"{keyValue[0]}=****");
                else
                    maskedParts.Add(part);
            }
            else
            {
                maskedParts.Add(part);
            }
        }

        return string.Join(";", maskedParts);
    }

    /// <summary>
    /// 验证配置完整性
    /// </summary>
    /// <param name="configType">配置类型</param>
    /// <returns>验证结果</returns>
    public static (bool IsValid, List<string> Errors) ValidateConfiguration(string configType)
    {
        var errors = new List<string>();

        try
        {
            switch (configType.ToLower())
            {
                case "database":
                    ValidateDatabaseConfiguration(errors);
                    break;
                case "cache":
                    ValidateCacheConfiguration(errors);
                    break;
                case "cloudstorage":
                    ValidateCloudStorageConfiguration(errors);
                    break;
                case "permission":
                    ValidatePermissionConfiguration(errors);
                    break;
                case "cors":
                    ValidateCorsConfiguration(errors);
                    break;
                default:
                    errors.Add($"未知的配置类型: {configType}");
                    break;
            }
        }
        catch (Exception ex)
        {
            errors.Add($"配置验证异常: {ex.Message}");
        }

        return (errors.Count == 0, errors);
    }

    /// <summary>
    /// 验证数据库配置
    /// </summary>
    private static void ValidateDatabaseConfiguration(List<string> errors)
    {
        var dbConfig = ConfigurationAccessor.DatabaseConfig;
        
        if (string.IsNullOrEmpty(dbConfig.DatabaseType))
        {
            errors.Add("数据库类型不能为空");
        }

        var connectionString = GetDatabaseConnectionString(dbConfig.DatabaseType);
        if (string.IsNullOrEmpty(connectionString))
        {
            errors.Add($"数据库连接字符串未配置: {dbConfig.DatabaseType}");
        }
    }

    /// <summary>
    /// 验证缓存配置
    /// </summary>
    private static void ValidateCacheConfiguration(List<string> errors)
    {
        var cacheConfig = ConfigurationAccessor.CacheConfig;
        
        if (string.IsNullOrEmpty(cacheConfig.Type))
        {
            errors.Add("缓存类型不能为空");
        }

        if (string.Equals(cacheConfig.Type, "redis", StringComparison.OrdinalIgnoreCase)
            && string.IsNullOrEmpty(cacheConfig.Redis?.ConnectionString))
        {
            errors.Add("Redis缓存连接字符串未配置");
        }
    }

    /// <summary>
    /// 验证云存储配置
    /// </summary>
    private static void ValidateCloudStorageConfiguration(List<string> errors)
    {
        var cloudConfig = ConfigurationAccessor.CloudStorageConfig;
        
        if (cloudConfig.AliyunOss.Enabled)
        {
            if (string.IsNullOrEmpty(cloudConfig.AliyunOss.Endpoint))
                errors.Add("阿里云OSS端点未配置");
            
            if (string.IsNullOrEmpty(cloudConfig.AliyunOss.AccessKeyId))
                errors.Add("阿里云OSS访问密钥ID未配置");
            
            if (string.IsNullOrEmpty(cloudConfig.AliyunOss.AccessKeySecret))
                errors.Add("阿里云OSS访问密钥密码未配置");
            
            if (string.IsNullOrEmpty(cloudConfig.AliyunOss.BucketName))
                errors.Add("阿里云OSS存储桶名称未配置");
        }
    }

    /// <summary>
    /// 验证权限配置
    /// </summary>
    private static void ValidatePermissionConfiguration(List<string> errors)
    {
        var permissionConfig = ConfigurationAccessor.PermissionConfig;
        
        if (permissionConfig.Enabled && (permissionConfig.AdminRoles?.Count ?? 0) == 0)
        {
            errors.Add("启用权限时必须配置至少一个管理员角色");
        }
    }

    /// <summary>
    /// 验证CORS配置
    /// </summary>
    private static void ValidateCorsConfiguration(List<string> errors)
    {
        var corsConfig = ConfigurationAccessor.CorsConfig;
        
        if (corsConfig.Enabled && (corsConfig.AllowedOrigins?.Count ?? 0) == 0)
        {
            errors.Add("启用CORS时必须配置允许的源");
        }
    }

    #endregion
}
